package com.yy.wga.user.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yy.wga.common.core.dto.BaseFeignApiReqDTO;
import com.yy.wga.common.core.enmus.EUserGrade;
import com.yy.wga.common.util.mapping.BeansUtils;
import com.yy.wga.user.feign.request.SaveUserAddressReq;
import com.yy.wga.user.feign.request.UserAddressByLngLatReq;
import com.yy.wga.user.feign.request.UserUpdateLevelReq;
import com.yy.wga.user.feign.response.UserAddressResp;
import com.yy.wga.user.service.enums.GradeRecordType;
import com.yy.wga.user.service.mapper.*;
import com.yy.wga.user.service.pojo.*;
import com.yy.wga.user.service.service.UserBaseService;
import com.yy.wga.user.service.service.UserSummaryService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

/**
 * 账号主表(UserBase)表服务实现类
 *
 * @author guochao
 * @since 2022-05-24 21:41:16
 */
@Service
public class UserBaseServiceImpl extends ServiceImpl<UserBaseMapper, UserBaseDO> implements UserBaseService {
    @Resource
    private UserBaseMapper userBaseMapper;
    @Resource
    private UserRelationMapper userRelationMapper;
    @Resource
    private UserGradeRecordMapper userGradeRecordMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private UserBaseAddressMapper userBaseAddressMapper;
    @Resource
    private UserSummaryService userSummaryService;

    @Override
    public void realRemoveById(Long userId) {
        baseMapper.realRemoveById(userId);
    }

    /**
     * @author TongSN
     * @Date 19:09 2025/2/18
     **/
    @Transactional(rollbackFor = SQLException.class)
    @Override
    public void updateUserLevelAndClearCache(UserUpdateLevelReq request) {
        // 1. 查询用户之前的等级信息
        UserBaseDO previousGradeInfo = userBaseMapper.selectById(request.getUserId());
        Integer beforeGrade = previousGradeInfo.getGrade();
        Integer beforeLevel = previousGradeInfo.getLevel();
        String appKey = previousGradeInfo.getAppKey();
        // 2.修改不能等级相同，且得合法
        EUserGrade requestEUserGrade = EUserGrade.getByType(request.getGrade(), request.getLevel());
        if (requestEUserGrade == null) {
            throw new RuntimeException("修改失败，等级不合法");
        }
        EUserGrade beforeUserGrade = EUserGrade.getByType(beforeGrade, beforeLevel);
        int compareResult = requestEUserGrade.compare(beforeUserGrade);
        if (compareResult == 0) {
            throw new RuntimeException("修改失败，等级相同");
        }
        // 3. 修改数据库中的用户等级信息
        baseMapper.update(null, new LambdaUpdateWrapper<UserBaseDO>()
                .eq(UserBaseDO::getId, request.getUserId())
                .set(UserBaseDO::getGrade, request.getGrade())
                .set(UserBaseDO::getLevel, request.getLevel())
                .set(UserBaseDO::getUpdateTime, new Date()));
        userRelationMapper.update(null, new LambdaUpdateWrapper<UserRelationDO>()
                .eq(UserRelationDO::getUserId, request.getUserId())
                .set(UserRelationDO::getGrade, request.getGrade())
                .set(UserRelationDO::getLevel, request.getLevel())
                .set(UserRelationDO::getUpdateTime, new Date()));
        userRelationMapper.update(null, new LambdaUpdateWrapper<UserRelationDO>()
                .eq(UserRelationDO::getParentUserId, request.getUserId())
                .set(UserRelationDO::getParentGrade, request.getGrade())
                .set(UserRelationDO::getParentLevel, request.getLevel())
                .set(UserRelationDO::getUpdateTime, new Date()));
        UserGradeRecordDO userGradeRecordDO = new UserGradeRecordDO();
        userGradeRecordDO.setAppKey(appKey);
        userGradeRecordDO.setUserId(request.getUserId());
        userGradeRecordDO.setGrade(request.getGrade());
        userGradeRecordDO.setLevel(request.getLevel());
        userGradeRecordDO.setBeforeGrade(beforeGrade);
        userGradeRecordDO.setBeforeLevel(beforeLevel);
        userGradeRecordDO.setType(GradeRecordType.UPDATE_GRADE.getType());
        userGradeRecordMapper.insert(userGradeRecordDO);
        // 4. 修改数据库中的用户销售额信息
        if (!EUserGrade.SERVER_1.getType().equals(request.getGrade())) {
            UserSummaryDO updateUserSummaryDO = new UserSummaryDO();
            LocalDateTime now = LocalDateTime.now();
            Instant instant = now.atZone(ZoneId.systemDefault()).toInstant();
            updateUserSummaryDO.setUpdateTime(Date.from(instant));
            updateUserSummaryDO.setUserId(request.getUserId());
            updateUserSummaryDO.setAppKey(appKey);
            updateUserSummaryDO.setSaleAmount(requestEUserGrade.getSalesThreshold());
            if (compareResult == 1) {
                userSummaryService.updateInfo(updateUserSummaryDO);
            } else if (compareResult == -1) {
                userSummaryService.downInfo(updateUserSummaryDO);
            }
        }
        // 4. 删除 Redis 中与该用户相关的缓存
        // 获取 TOKEN 值，并用该值获取 USER_INFO 键
        String tokenKey = "TOKEN:" + request.getUserId();
        String tokenValue = stringRedisTemplate.opsForValue().get(tokenKey);
        if (tokenValue != null) {
            // 删除 TOKEN 和 USER_INFO 缓存
            stringRedisTemplate.delete(tokenKey);
            stringRedisTemplate.delete(tokenValue);
        }
    }

    @Override
    public void saveUserAddress(SaveUserAddressReq request) {
        Long userId = request.getUserId();
        UserBaseDO userBaseDO = userBaseMapper.selectOne(new LambdaQueryWrapper<UserBaseDO>()
                .eq(UserBaseDO::getId, userId)
                .eq(UserBaseDO::getStatus, 1));
        if (userBaseDO == null) {
            throw new RuntimeException("用户账号异常");
        }
        // todo
        /*ResourceRegionResp regionResp = resourceRegionManage.queryRegionByCode(request.getProvinceCode());
        if (regionResp == null) {
            throw new RuntimeException("请正确选择省份编码");
        }
        if (!regionResp.getRegionName().equals(request.getProvince())) {
            throw new RuntimeException("请核对省份编码与省份名称");
        }
        regionResp = resourceRegionManage.queryRegionByCode(request.getCityCode());
        if (regionResp == null) {
            throw new RuntimeException("请正确选择城市编码");
        }
        if (!regionResp.getRegionName().equals(request.getCity())) {
            throw new RuntimeException("请核对城市编码与城市名称");
        }
        regionResp = resourceRegionManage.queryRegionByCode(request.getAreaCode());
        if (regionResp == null) {
            throw new RuntimeException("请正确选择地区编码");
        }
        if (!regionResp.getRegionName().equals(request.getArea())) {
            throw new RuntimeException("请核对地区编码与地区名称");
        }*/
        UserBaseAddressDO userBaseAddressDO = userBaseAddressMapper.selectOne(new LambdaQueryWrapper<UserBaseAddressDO>()
                .eq(UserBaseAddressDO::getUserId, userId));
        if (userBaseAddressDO == null) {
            userBaseAddressDO = new UserBaseAddressDO();
            BeansUtils.copyProperties(request, userBaseAddressDO);
            userBaseAddressDO.setAppKey(request.getAppKey());
            userBaseAddressDO.setUserId(userId);
            userBaseAddressMapper.insert(userBaseAddressDO);
        } else {
            BeansUtils.copyProperties(request, userBaseAddressDO);
            userBaseAddressMapper.updateById(userBaseAddressDO);
        }
    }

    @Override
    public UserAddressResp getUserAddress(BaseFeignApiReqDTO reqDTO) {
        UserBaseAddressDO userBaseAddressDO = userBaseAddressMapper.selectOne(new LambdaQueryWrapper<UserBaseAddressDO>()
                .eq(UserBaseAddressDO::getUserId, reqDTO.getUserId()));
        return BeansUtils.map(userBaseAddressDO, UserAddressResp.class);
    }

    @Override
    public UserAddressResp getUserAddressByLngLat(UserAddressByLngLatReq req) {
        UserBaseAddressDO userBaseAddressDO = userBaseAddressMapper.selectOne(new LambdaQueryWrapper<UserBaseAddressDO>()
                .eq(UserBaseAddressDO::getUserId, req.getUserId()));
        // 用户存在地址信息直接返回
        if (userBaseAddressDO != null) {
            return BeansUtils.map(userBaseAddressDO, UserAddressResp.class);
        }
        // 不存在用户地址信息，新增用户地址信息并返回
        // todo
        //ResourceRegionInfoResp regionResp = resourceRegionManage.queryAddress(req.getLng(), req.getLat());
        userBaseAddressDO = new UserBaseAddressDO();
        //BeansUtils.copyProperties(regionResp, userBaseAddressDO);
        userBaseAddressDO.setAppKey(req.getAppKey());
        userBaseAddressDO.setUserId(req.getUserId());
        userBaseAddressDO.setLocation(req.getLng() + "," + req.getLat());
        userBaseAddressMapper.insert(userBaseAddressDO);
        return BeansUtils.map(userBaseAddressDO, UserAddressResp.class);
    }
}
